﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace CodeC.Utilities
{
    public static partial class CodeCExtension
    {

        #region "Constant"

        #region Keyword List

        private static List<string> _listOfKeywords = new List<string> {         
                                                        "abstract",
                                                        "add",
                                                        "alias",
                                                        "as",
                                                        "ascending",
                                                        "async",
                                                        "await",
                                                        "base",
                                                        "bool",
                                                        "break",
                                                        "byte",
                                                        "case",
                                                        "catch",
                                                        "char",
                                                        "checked",
                                                        "class",
                                                        "const",
                                                        "continue",
                                                        "decimal",
                                                        "default",
                                                        "delegate",
                                                        "descending",
                                                        "do",
                                                        "double",
                                                        "dynamic",
                                                        "else",
                                                        "enum",
                                                        "event",
                                                        "explicit",
                                                        "extern",
                                                        "finally",
                                                        "fixed",
                                                        "float",
                                                        "for",
                                                        "foreach",
                                                        "from",
                                                        "get",
                                                        "global",
                                                        "goto",
                                                        "group",
                                                        "if",
                                                        "implicit",
                                                        "in",
                                                        "int",
                                                        "interface",
                                                        "internal",
                                                        "into",
                                                        "is",
                                                        "join",
                                                        "let",
                                                        "lock",
                                                        "long",
                                                        "namespace",
                                                        "new",
                                                        "null",
                                                        "object",
                                                        "operator",
                                                        "orderby",
                                                        "out",
                                                        "override",
                                                        "params",
                                                        "partial",
                                                        "private",
                                                        "protected",
                                                        "public",
                                                        "readonly",
                                                        "ref",
                                                        "remove",
                                                        "return",
                                                        "sbyte",
                                                        "sealed",
                                                        "select",
                                                        "set",
                                                        "short",
                                                        "sizeof",
                                                        "stackalloc",
                                                        "static",
                                                        "string",
                                                        "struct",
                                                        "switch",
                                                        "this",
                                                        "throw",
                                                        "try",
                                                        "typeof",
                                                        "uint",
                                                        "ulong",
                                                        "unchecked",
                                                        "unsafe",
                                                        "ushort",
                                                        "using",
                                                        "value",
                                                        "var",
                                                        "virtual",
                                                        "void",
                                                        "volatile",
                                                        "where",
                                                        "while",
                                                        "yield",
                                                        "FALSE",
                                                        "TRUE"
                                                };

        #endregion

        #endregion

        #region "Static Methods"


        /// <summary>
        /// Get String between two strings
        /// </summary>
        /// <param name="str"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public static string Between(this string str, string start, string end)
        {
            if (null == str) return null;

            return (str.IndexOf(end, str.IndexOf(start)) - (str.IndexOf(start) + start.Length)) > 0 ?
                str.Substring(str.IndexOf(start) + start.Length, str.IndexOf(end, str.IndexOf(start)) - (str.IndexOf(start) + start.Length)) : str;

        }

        /// <summary>
        /// Replace special character used in WPLDB
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ReplaceNewLine(this string str)
        {
            if (null == str) return null;
            return str.Replace("[NEWLINE]", Environment.NewLine).Replace("[T]", "    ");

        }

        /// <summary>
        /// Replace [CLASSMETHODS] string with given string
        /// </summary>
        /// <param name="str"></param>
        /// <param name="classMethods"></param>
        /// <returns></returns>
        public static string ReplaceClassMethods(this string str, string classMethods)
        {
            if (null == str) return null;
            return str.Replace("[CLASSMETHODS]", classMethods);
        }

        /// <summary>
        /// Replace [MAINCODECONTENT] string with given string
        /// </summary>
        /// <param name="str"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string ReplaceMainCodeContent(this string str, string content)
        {
            if (null == str) return null;
            return str.Replace("[MAINCODECONTENT]", content);

        }

        /// <summary>
        /// Check IsNuallOrEmpty sting
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string str)
        {
            return string.IsNullOrWhiteSpace(str);

        }

        /// <summary>
        ///  Check Not IsNuallOrEmpty sting
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsNotNullOrNotEmpty(this string str)
        {
            return !string.IsNullOrWhiteSpace(str);
        }

        /// <summary>
        /// Remove last charactor of a string
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string RemoveLastChar(this string str)
        {
            return null == str ? null : str.Length > 0 ? str.Substring(0, str.Length - 1) : str;
        }

        /// <summary>
        /// Remove special charactor from a string
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string RemoveSpecialChar(this string str)
        {
            return null == str ? null : new Regex(@"([!@#$%^&*: ;\-()]|(?:[.](?![a-z0-9]+$)))", RegexOptions.IgnoreCase).Replace(str, "");
        }

        /// <summary>
        /// Returns No. of new line characters in the string.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int LineCount(this string str)
        {
            int lineCount = 0;

            if (null != str)
            {
                var strArray = str.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
                if (null != strArray)
                    lineCount = strArray.Count();
            }

            return lineCount;
        }

        /// <summary>
        /// Select the text in the mentioned line no. in text box.
        /// </summary>
        /// <param name="textBox"></param>
        /// <param name="lineNo"></param>
        public static void HighlightLine(this System.Windows.Controls.TextBox textBox, int lineNo)
        {
            string str = textBox.Text;
            string[] strArray = str.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
            if (strArray.Length > lineNo - 1 && lineNo > 0)
            {

                string erString = strArray[lineNo - 1];
                int index = str.IndexOf(erString);
                string output = str.Substring(index, erString.Length);

                textBox.Focus();
                textBox.Select(index, erString.Length);
            }

        }

        /// <summary>
        /// Set XML Element 
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <param name="elemName"></param>
        /// <param name="elemValue"></param>
        /// <returns></returns>
        public static XmlElement SetXmlElement(this XmlDocument xmlDoc, string elemName, string elemValue)
        {
            XmlElement xmlElement = xmlDoc.CreateElement(elemName);
            xmlElement.InnerText = elemValue;

            return xmlElement;
        }

        /// <summary>
        /// Replace [CLASSMETHODS] string with given string
        /// </summary>
        /// <param name="str"></param>
        /// <param name="namespaces"></param>
        /// <returns></returns>
        public static string ReplaceNamespaces(this string str, string namespaces)
        {
            if (null == str) return null;
            return str.Replace("[NAMESPACES]", namespaces);
        }

        /// <summary>
        /// Replace 'Console.Read' string with UPPER CASE 'CONSOLE.READ'
        /// </summary>
        /// <param name="str"></param>
        /// <param name="namespaces"></param>
        /// <returns></returns>
        public static string ReplaceConsoleRead(this string str)
        {
            if (null == str) return null;
            return str.Replace("Console.Read", "CONSOLE.READ");
        }

        /// <summary>
        /// Replace 'CONSOLE.READ' string with Normal Code 'Console.Read'
        /// </summary>
        /// <param name="str"></param>
        /// <param name="namespaces"></param>
        /// <returns></returns>
        public static string ReplaceCONSOLEREAD(this string str)
        {
            if (null == str) return null;
            return str.Replace("CONSOLE.READ", "Console.Read").Replace("CONSOLE", "Console.Read");
        }

        #endregion
    }
}
